package org.jkuang.qstar.commons.io;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileReader

{
	long length;
	long offset;
	BufferedInputStream in;

	byte[] bs8 = new byte[8];

	public FileReader(File file) throws FileNotFoundException {
		this.offset = 0;
		this.length = file.length();
		this.in = new BufferedInputStream(new FileInputStream(file), 1024 * 1024 * 4);
	}

	public boolean hasMore() {
		return this.offset<this.length;
	}
	
	public boolean hasMore(long size) {
		return this.offset+size<=this.length;
	}

	public byte[] readBytes(int len) throws IOException {
		byte[] data = new byte[len];
		this.in.read(data);
		this.offset +=len;
		return data;
	}

	public byte[] readShortBytes() throws IOException {
		short len = readShort();
		return readBytes(len);
	}

	public byte[] readIntBytes() throws IOException {
		int len = readInt();
		return readBytes(len);
	}

	public byte readByte() throws IOException {
		in.read(bs8, 0, 1);
		this.offset+=1;
		return bs8[0];
	}

	public short readShort() throws IOException {
		in.read(bs8, 0, 2);
		this.offset+=2;
		return readShort(bs8, 0);
	}

	public int readInt() throws IOException {
		in.read(bs8, 0, 4);
		this.offset+=4;
		return readInt(bs8, 0);
	}

	public long readLong() throws IOException {
		in.read(bs8, 0, 8);
		this.offset+=8;
		return readLong(bs8, 0);
	}

	public short readShort(byte[] bs, int pos) {
		return (short) (bs[pos++] << 8 & 0xff00 | bs[pos++] & 0xff);
	}

	public int readInt(byte[] bs, int pos) {
		return (bs[pos++] << 24) & 0xff000000 | (bs[pos++] << 16) & 0xff0000 | (bs[pos++] << 8) & 0xff00

				| bs[pos++] & 0xff;
	}

	public long readLong(byte[] bs, int pos) {
		return ((bs[pos++] & 0xffl) << 56) | ((bs[pos++] & 0xffl) << 48) | ((bs[pos++] & 0xffl) << 40)

				| ((bs[pos++] & 0xffl) << 32) | ((bs[pos++] & 0xffl) << 24) | ((bs[pos++] & 0xffl) << 16)

				| ((bs[pos++] & 0xffl) << 8) | ((bs[pos++] & 0xffl) << 0);
	}

	public void close() {
		if (in != null) {
			try {
				in.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}
